// 首先监听游戏开始
import { AppType, CardProps } from '@/Util/Constant';
import { PixiBase } from '@/game/baseClass/PixiBase';
import { Broadcaster, DataChange, EventType } from '@/game/broadcaster/Broadcaster';
import { Card } from './card';
import Hlddz from '@/game/model/hlddz';
import { CardType, DoubleMsgType, DoubleType, GameStatus, OutCardInfo, OutCardType, SocketDataType, SocketEventType } from '@/share/commonType';
import * as PIXI from 'pixi.js'
import { Button } from '../button/button';
import { ButtonProps } from '@/Util/Constant'
import { ElMessage } from 'element-plus';
import socket from '@/socket/UserChatSocket';
import { CardList } from '../player/cardList';
import { Util } from '@/Util';
import eventBus from '@/Util/EventBus';
import { Timer } from '../button/timer';
const TextureCache = PIXI.utils.TextureCache


export class CardController extends PixiBase {
    model: Hlddz = Hlddz.getInstance();
    choiceCards: CardType[] = []; // 选中的牌在controller中控制，这个数据我们也需要传递给后端，广播给其他客户端。
    isMultipleChoice: boolean = false;
    multipleChoiceCard: CardType = null; // 当前选中的card
    cardMap: Map<string, Card> = new Map()// string为cardNum + cardIcon
    cardContainer: PIXI.Container = new PIXI.Container();
    outCardContainer: PIXI.Container = new PIXI.Container(); // 展示出牌的容器
    outCardButtons: PIXI.Container = new PIXI.Container();
    doubleButtons: PIXI.Container = new PIXI.Container();
    landlordContainer: PIXI.Container = new PIXI.Container(); // 地主icon
    landlordCardContainer: PIXI.Container = new PIXI.Container(); // 地主牌
    timer: Timer;
    myName: string;
    outCardList: CardList;
    landCardList: CardList;
    tipCardList: CardType[][];
    tipCardListLen: number = 0;
    tipCardIndex: number = 0;
    cardWidth: number;
    cardSpacing: number;
    constructor(public app: AppType) {
        super(app)
        this.addListener(this.model)
        this.cardWidth = 135 * this.scaleSize
        this.cardSpacing = 38 * this.scaleSize
        this.baseContainer.addChild(this.cardContainer)
        this.baseContainer.addChild(this.outCardButtons)
        this.baseContainer.addChild(this.doubleButtons)
        this.baseContainer.addChild(this.outCardContainer)
        this.baseContainer.addChild(this.landlordContainer)
        this.baseContainer.addChild(this.landlordCardContainer)
        this.outCardList = new CardList(this.outCardContainer)
        this.landCardList = new CardList(this.landlordCardContainer)
        eventBus.on('outcard', this.outCard)
    }
    createTimer() {
        this.timer = new Timer({
            baseContainer: this.baseContainer,
            scaleSize: this.scaleSize,
            posX: (window.innerWidth - TextureCache['timer'].width * this.scaleSize) / 2,
            posY: window.innerHeight - 325 * this.scaleSize
        })
    }

    createGameButton() {
        this.outCardButtons.visible = false
        let buttonConfig: ButtonProps[] = [
            { container: this.outCardButtons, text: "出牌", bgColor: '#68bceb', handler: this.outCard },
            { container: this.outCardButtons, text: "不出", bgColor: '#da3358', handler: this.skip },
            { container: this.outCardButtons, text: "提示", bgColor: '#18db0c', handler: this.tipCard },
            { container: this.outCardButtons, text: "重选", bgColor: '#697ea0', handler: this.reselection }
        ]
        buttonConfig.forEach((item, index) => {
            let props: ButtonProps = Object.assign(item, { posX: index * 120, scaleSize: this.scaleSize })
            new Button(props)
        })
        this.outCardButtons.x = (window.innerWidth - this.outCardButtons.width) / 2
        this.outCardButtons.y = window.innerHeight - 265 * this.scaleSize
    }

    createDoubleButton() {
        this.doubleButtons.visible = false
        let buttonConfig: ButtonProps[] = [
            { container: this.doubleButtons, text: "超级加倍 ×4", bgColor: '#68bceb', width: 150, handler: () => this.doubleHandler(DoubleType.SuperDouble) },
            { container: this.doubleButtons, text: "加倍 ×2", bgColor: '#da3358', width: 150, handler: () => this.doubleHandler(DoubleType.Double) },
            { container: this.doubleButtons, text: "不加倍", bgColor: '#18db0c', width: 150, handler: () => this.doubleHandler(DoubleType.None) },
        ]
        buttonConfig.forEach((item, index) => {
            let props: ButtonProps = Object.assign(item, { posX: index * 150, scaleSize: this.scaleSize })
            new Button(props)
        })
        this.doubleButtons.x = (window.innerWidth - this.doubleButtons.width) / 2
        this.doubleButtons.y = window.innerHeight - 265 * this.scaleSize
    }

    doubleHandler = (doubleType: DoubleType) => {
        this.doubleButtons.visible = false
        socket.emit({
            action: SocketEventType.DdzGame,
            dataType: SocketDataType.Double,
            data: {
                playerName: this.myName,
                gameId: this.model.gameId,
                doubleType
            }
        })
    }

    outCard = () => {
        // 判断当前选中的牌和上次的牌谁大谁小
        if (this.model.gameStatus !== GameStatus.Gaming) return;
        if (this.model.nowOutCardPlayer !== this.myName) return;
        if (!this.tipCardListLen) {
            this.skip()
            return
        }
        let outCardInfo = this.getOutCardInfo(this.choiceCards)
        if (outCardInfo.type === OutCardType.None) {
            ElMessage({
                message: '你出的牌不符合规范',
                type: 'error'
            })
            return;
        }
        // 判断当前的牌是否大于对方的牌
        if (this.model.compareCardInfo && this.model.compareCardInfo.type !== OutCardType.EMPTY_CARD_FLAG) {
            if (!this.compareCard(outCardInfo, this.model.compareCardInfo)) {
                ElMessage({
                    message: '你的牌不能大过对方',
                    type: 'error'
                })
                return; // 后续需要界面文字提示
            }
        }
        //发送出牌消息和出牌信息，并关闭gameButton
        let cardInfo = {
            playerName: this.myName,
            gameId: this.model.gameId,
            outCardInfo,
        }
        socket.emit({
            action: SocketEventType.DdzGame,
            dataType: SocketDataType.OutCard,
            data: cardInfo
        })
        this.outCardButtons.visible = false
        this.timer.endInterVal()
        this.model.outCard(cardInfo)
        this.model.clientOutCard(cardInfo?.outCardInfo?.rawCards)
        this.renderOutCard(this.choiceCards)
        this.choiceCards = []
    }

    compareCard(myCardInfo: OutCardInfo, compareCardInfo: OutCardInfo): boolean {
        if (!compareCardInfo) return true;
        let myType = myCardInfo.type
        let compareType = compareCardInfo.type
        let myCompareNum = myCardInfo.compareNum
        let compareNum = compareCardInfo.compareNum
        if (compareType === OutCardType.KingBomb) return false; // 王炸大于一切
        if (myType === OutCardType.KingBomb) return true; // 王炸大于一切
        if (compareType === OutCardType.Bomb) {
            if (myType !== OutCardType.Bomb) return false;
            return myCompareNum > compareNum // 都是炸弹，比谁的炸弹大
        } else { // 不是炸弹
            if (myType === OutCardType.Bomb) return true;
            if (myType !== compareType) return false; // 不是炸弹，出牌类型必须一致
            if (myType === OutCardType.Shunzi || myType === OutCardType.ConnectedPair || myType === OutCardType.AirFly) {
                if (myCardInfo.connectSize !== compareCardInfo.connectSize) return false;
            }
            return myCompareNum > compareNum;
        }
    }

    renderOutCard(renderCards: CardType[]) {
        if (renderCards) {
            renderCards.forEach(({ cardNum, cardIcon }) => { // 把牌删除掉
                let cardId = `${cardNum}-${cardIcon}`
                let card = this.cardMap.get(cardId)
                card.removeChild()
                this.cardMap.delete(cardId)
            })
            // 把剩下的牌合并
            let cardCount = this.cardMap.size;
            // 需要计算出起始点，然后按index往自己应该在的位置移动
            let cardTotalWidth = this.getCardListWidth(cardCount)
            let startX = (window.innerWidth - cardTotalWidth) / 2
            let index = 0
            for (const card of this.cardMap.values()) {
                card.merge(startX + index * this.cardSpacing - this.cardContainer.x)
                index++
            }
        }
        // 展示出牌
        let length = (this.choiceCard.length - 1) * this.cardSpacing + this.cardWidth
        let posX = (window.innerWidth - length) / 2
        let posY = this.cardContainer.y - 160 * this.scaleSize
        this.outCardList.changeCard({ cardList: renderCards, posX, posY, scaleSize: this.scaleSize })
    }

    getCardListWidth(count: number) {
        return (count - 1) * this.cardSpacing + this.cardWidth
    }
    skip = () => {
        // 发送一条不出的消息，并关闭gameButton
        if (!this.model.compareCardInfo || this.model.compareCardInfo.type === OutCardType.EMPTY_CARD_FLAG) {
            ElMessage({
                message: '当前属于你的回合，不能跳过哦',
                type: 'warning'
            })
            eventBus.emit('timerAlert')
            return;
        }
        socket.emit({
            action: SocketEventType.DdzGame,
            dataType: SocketDataType.OutCard,
            data: {
                playerName: this.myName, // 不出的话 outCardInfo为空
                gameId: this.model.gameId,
                outCardInfo: null
            }
        })
        this.outCardButtons.visible = false
        this.timer.endInterVal()
        this.renderOutCard(null)
    }
    tipCard = () => {
        if (!this.tipCardListLen) {
            ElMessage({
                message: '当前没有牌能大过对方',
                type: 'error'
            })
            return;
        }
        if (this.tipCardIndex >= this.tipCardListLen) this.tipCardIndex = 0;

        let tipCards = Util.deepClone<CardType[]>(this.tipCardList[this.tipCardIndex]);
        let tipCard2 = Util.deepClone<CardType[]>(this.tipCardList[this.tipCardIndex]);
        this.tipCardIndex++
        this.choiceCards.forEach(({ cardNum, cardIcon }) => {
            let cardIndex = tipCards.findIndex((item) => item.cardIcon === cardIcon && item.cardNum === cardNum)
            if (cardIndex === -1) {
                let card = this.getCardByCardType({ cardNum, cardIcon })
                card && card.choiceCard(true)
            } else {
                tipCards.splice(cardIndex, 1)
            }
        })
        tipCards.forEach((item) => {
            let card = this.getCardByCardType(item)
            card && card.choiceCard()
        })
        this.choiceCards = tipCard2
    }
    calculateTipCardList() {
        this.tipCardList = []
        let compareCardInfo = this.model.compareCardInfo
        let cardList = this.model.card;
        let cardNumArr: CardType[][] = [] // 下标是牌的号码
        let cardCountArr: number[][] = [[], [], [], []] // 下标是牌的数量
        cardList.forEach((card) => {
            if (cardNumArr[card.cardNum]) {
                cardNumArr[card.cardNum].push(card)
            } else {
                cardNumArr[card.cardNum] = [card]
            }
        })
        cardNumArr.forEach((cardList: CardType[]) => {
            let cardNum = cardList[0].cardNum
            let len = cardList.length
            if (len > 3) cardCountArr[3].unshift(cardNum); //大的放后边，小的放前边
            if (len > 2) cardCountArr[2].unshift(cardNum);
            if (len > 1) cardCountArr[1].unshift(cardNum);
            if (len > 0) cardCountArr[0].unshift(cardNum);
        })
        // 计算提示牌数组
        let bombList: CardType[][] = cardCountArr[3].map((cardNum: number) => cardNumArr[cardNum].slice(0, 4)) //炸弹列表
        if (cardNumArr[14] && cardNumArr[15]) { this.tipCardList.unshift([cardNumArr[14][0], cardNumArr[15][0]]) } //有王炸直接推进去
        if (!compareCardInfo || compareCardInfo.type === OutCardType.EMPTY_CARD_FLAG) { // 上一个出牌人是自己，只推荐单一牌
            let cardCountLit = cardCountArr[0]
            cardCountLit.forEach((item: number) => {
                let cards = cardNumArr[item]
                this.tipCardList.unshift(cards.slice(0, 1))
            })
        } else {
            let lastCardsType = compareCardInfo.type;
            let compareNum = compareCardInfo.compareNum;
            let connectSize = compareCardInfo.connectSize;
            if (lastCardsType === OutCardType.Bomb) { //找出比他大的炸弹
                cardCountArr[3].forEach((cardNum: number) => {
                    if (cardNum > compareNum) {
                        this.tipCardList.unshift(cardNumArr[cardNum])
                    }
                }) //炸弹列表
            } else {
                this.tipCardList.unshift(...bombList) // 把所有炸弹推进去
                if (lastCardsType === OutCardType.Single) {
                    cardCountArr[0].forEach((cardNum: number) => { //从单牌列表里找
                        if (cardNum > compareNum) {
                            this.tipCardList.unshift(cardNumArr[cardNum].slice(0, 1))
                        }
                    })
                } else if (lastCardsType === OutCardType.Double) {
                    cardCountArr[1].forEach((cardNum: number) => {
                        if (cardNum > compareNum) {
                            this.tipCardList.unshift(cardNumArr[cardNum].slice(0, 2))
                        }
                    })
                } else if (lastCardsType === OutCardType.Three) {
                    cardCountArr[2].forEach((cardNum: number) => {
                        if (cardNum > compareNum) {
                            this.tipCardList.unshift(cardNumArr[cardNum].slice(0, 3))
                        }
                    })
                } else if (lastCardsType === OutCardType.ThreeWithOne || lastCardsType === OutCardType.ThreeWithTwo) {
                    let isThreeWithOne = lastCardsType === OutCardType.ThreeWithOne
                    cardCountArr[2].forEach((mainCardNum: number) => {
                        if (mainCardNum > compareNum) {
                            let subArr = cardCountArr[isThreeWithOne ? 0 : 1]
                            if (subArr.length - 1 == 0) return;
                            subArr.forEach((cardNum: number) => {
                                if (cardNum !== mainCardNum) {
                                    this.tipCardList.unshift([...cardNumArr[mainCardNum].slice(0, 3), ...cardNumArr[cardNum].slice(0, isThreeWithOne ? 1 : 2)])
                                }
                            })
                        }
                    })
                } else if (lastCardsType === OutCardType.FourWithTwo || lastCardsType === OutCardType.FourWithFour) { // 四带二默认只带最小的单或对
                    let isFourWithTwo = lastCardsType === OutCardType.FourWithTwo;
                    cardCountArr[3].forEach((mainCardNum: number) => {
                        if (mainCardNum > compareNum) {
                            let oneTwoArr = cardCountArr[isFourWithTwo ? 0 : 1]
                            if (oneTwoArr.length - 1 >= 2) {
                                this.tipCardList.unshift([...cardNumArr[mainCardNum].slice(0, 3),
                                ...cardNumArr[oneTwoArr[0]].slice(0, isFourWithTwo ? 1 : 2),
                                ...cardNumArr[oneTwoArr[1]].slice(0, isFourWithTwo ? 1 : 2)
                                ])
                            }
                        }
                    })
                } else if (lastCardsType === OutCardType.Shunzi || lastCardsType === OutCardType.ConnectedPair) {
                    let cardCountArrIndex = lastCardsType === OutCardType.Shunzi ? 0 : 1;
                    let sliceIndex = lastCardsType === OutCardType.Shunzi ? 1 : 2;

                    if (cardCountArr[cardCountArrIndex].length >= connectSize) {
                        let connectedArr = this.getConnectedArr(cardCountArr[cardCountArrIndex], connectSize)
                        // 开始循环遍历connectedArr
                        connectedArr.forEach((arr) => {
                            if (arr.length >= connectSize && arr[0] > compareNum) { // 该连对的长度和最大值大于对方
                                let max = 0;
                                let min = connectSize - 1;
                                while (arr[max] > compareNum && min < arr.length) {
                                    // 收
                                    let resArr: CardType[] = [];
                                    for (let i = max; i <= min; i++) {
                                        resArr.push(...(cardNumArr[arr[i]].slice(0, sliceIndex)))
                                    }
                                    this.tipCardList.unshift(resArr)
                                    max += 1;
                                    min += 1;
                                }
                            }
                        })
                    }
                } else if (lastCardsType === OutCardType.AirFly || lastCardsType === OutCardType.AirFlyWithOne || lastCardsType === OutCardType.AirFlyWithTwo) {
                    if (cardCountArr[2].length < connectSize) return;
                    let subCardArr: CardType[] = [];
                    if (lastCardsType !== OutCardType.AirFly) {
                        if (lastCardsType === OutCardType.AirFlyWithOne && cardCountArr[0].length - connectSize < connectSize) return;
                        if (lastCardsType === OutCardType.AirFlyWithTwo && cardCountArr[1].length - connectSize < connectSize) return;
                        let index = lastCardsType === OutCardType.AirFlyWithOne ? 0 : 1
                        let sliceLen = lastCardsType === OutCardType.AirFlyWithOne ? 1 : 2
                        for (let i = 0; i < connectSize; i++) {
                            let cardNum = cardCountArr[index][i]
                            subCardArr.push(...cardNumArr[cardNum].slice(0, sliceLen))
                        }
                    }
                    let connectedArr = this.getConnectedArr(cardCountArr[2], connectSize)
                    // 开始循环遍历connectedArr
                    connectedArr.forEach((arr) => {
                        if (arr.length >= connectSize && arr[0] > compareNum) { // 该连对的长度和最大值大于对方
                            let max = 0;
                            let min = connectSize - 1;
                            while (arr[max] > compareNum && min < arr.length) {
                                // 收
                                let resArr: CardType[] = [];
                                for (let i = max; i <= min; i++) {
                                    resArr.push(...(cardNumArr[arr[i]].slice(0, 3)))
                                }
                                this.tipCardList.unshift([...resArr, ...subCardArr])
                                max += 1;
                                min += 1;
                            }
                        }
                    })

                }
            }
        }
    }

    getConnectedArr(cardCountArr: number[], connectSize: number) {
        let connectedArr = [];
        let beforeNum = cardCountArr[0];
        let temp = [];
        for (let i = 1; i < cardCountArr.length; i++) {
            let cardnum = cardCountArr[i];
            if (cardnum > 12) {
                beforeNum = cardnum;
                continue;
            }
            if (cardnum !== beforeNum - 1) {
                if (temp.length >= connectSize) {
                    connectedArr.push(temp)
                }
                temp = [];
            }
            temp.push(cardnum) // 从大到小
            beforeNum = cardnum;
        }
        if (temp.length >= connectSize) { // 最后一个元素命中cardnum == beforeNum - 1，但是没有收尾
            connectedArr.push(temp)
        }
        return connectedArr;
    }
    reselection = () => {
        this.choiceCards.forEach((item) => {
            let card = this.getCardByCardType(item)
            card && card.choiceCard(true)
        })
        this.choiceCards = []
    }
    getOutCardInfo(cards: CardType[]): OutCardInfo {
        let cardNums: number[] = cards.map((item) => item.cardNum)
        let len = cardNums.length;
        let cardType: OutCardType = OutCardType.None;
        let compareNum: number = 0;
        let connectSize: number = 0;
        let maxNum = cardNums[0] //最大的数字
        let minNum = cardNums[len - 1] // 最小的数字
        let cardMap = new Map<number, number>()
        cardNums.forEach((num) => {
            let n = cardMap.get(num) || 0
            cardMap.set(num, ++n)
        })
        let countArr = [] // 按出现次数排序的数组
        for (const iterator of cardMap.entries()) {
            countArr.push(iterator)
        }
        countArr.sort((a, b) => b[1] - a[1])
        let cardMapSize = cardMap.size
        if (len === 1) {
            cardType = OutCardType.Single
            compareNum = cardNums[0] // 单
        } else if (len === 2) {
            if (cardMapSize === 1) {
                cardType = OutCardType.Double // 对
                compareNum = cardNums[0]
            } else if (cardMapSize === 2 && cardMap.has(14) && cardMap.has(15)) {
                cardType = OutCardType.KingBomb // 王炸
            }
        } else if (len === 3 && cardMapSize === 1) {
            cardType = OutCardType.Three //三不带
            compareNum = cardNums[0]
        } else if (len === 4) {
            if (cardMapSize === 1) {
                cardType = OutCardType.Bomb // 炸弹
                compareNum = cardNums[0]
            } else if (cardMapSize === 2 && countArr[0][1] === 3) {
                cardType = OutCardType.ThreeWithOne // 三带一
                compareNum = countArr[0][0] // 不可能存在数一致的三带一
            }
        } else if (len === 5) {
            if (cardMapSize === 2 && countArr[0][1] === 3 && countArr[1][1] === 2) {
                cardType = OutCardType.ThreeWithTwo // 三带二
                compareNum = countArr[0][0]
            }
        } else if (len === 6) {
            if (cardMapSize === 2 && countArr[0][1] === 4 && countArr[1][1] === 2) {
                cardType = OutCardType.FourWithTwo // 四带二
                compareNum = countArr[0][0]
            }
        } else if (len === 8) {
            if (cardMapSize === 3 && countArr[0][1] === 4 && countArr[1][1] === 2 && countArr[2][1] === 2) {
                cardType = OutCardType.FourWithFour // 四带两对
                compareNum = countArr[0][0]
            }
        }

        if (len > 4) { //判断顺子，和连对
            if (maxNum < 13) { // 连对最大到 A
                if (len === cardMapSize && maxNum - minNum === len - 1) {
                    cardType = OutCardType.Shunzi // 顺子
                    compareNum = maxNum
                    connectSize = len
                } else if (len === 2 * cardMapSize) {
                    if (!countArr.some(item => item[1] !== 2) && maxNum - minNum === len / 2 - 1) {
                        cardType = OutCardType.ConnectedPair // 连对
                        compareNum = maxNum
                        connectSize = len
                    }
                }
            }
        }

        if (len >= 8) { // 飞机最少8张, 并且不包含2
            // 首先获取包含三张的有几个，都是谁
            let threeArr = []
            let twoArrLen = 0;
            let singleArrLen = 0;
            countArr.forEach((item) => { if (item[1] === 3) threeArr.push(item[0]); })
            countArr.forEach((item) => { if (item[1] === 2) twoArrLen++ })
            countArr.forEach((item) => { if (item[1] === 1) singleArrLen++ })
            let max = Math.max(...threeArr)
            let min = Math.min(...threeArr)
            if (!threeArr.includes(13) && max - min === threeArr.length - 1) {
                if (!twoArrLen || !singleArrLen) { // 不能同时存在带单和带对的情况, 可以不带
                    if (singleArrLen && singleArrLen === threeArr.length) { // 飞机带单
                        cardType = OutCardType.AirFlyWithOne
                    } else if (twoArrLen && twoArrLen === threeArr.length) {// 飞机带对
                        cardType = OutCardType.AirFlyWithTwo
                    } else {
                        cardType = OutCardType.AirFly // 飞机什么都不带
                    }
                    compareNum = max
                    connectSize = threeArr.length
                }
            }

        }
        return {
            type: cardType,
            rawCards: cards,
            compareNum,
            connectSize
        };
    }
    getCardByCardType(cardType: CardType): Card {
        let cardId = `${cardType.cardNum}-${cardType.cardIcon}`
        return this.cardMap.get(cardId)
    }

    gainOutCardRight() { //获得出牌权
        if (!this.model.nowOutCardPlayer || this.myName !== this.model.nowOutCardPlayer || this.timer.timer) return;
        if (!this.model.isCompleteDouble) return;
        this.initTipCardList()
        this.outCardList.clearCard()
        this.outCardButtons.visible = true
        this.timer.startInterVal(this.skip, true)
    }

    showDoubleButton() {
        if (this.model.isCompleteDouble || this.model.completeDoublePlayer.includes(this.myName)) return;
        this.doubleButtons.visible = true
    }

    createCards() {
        this.myName = this.model.userinfo.username
        let cards = this.model.card
        let cardCount = cards.length
        let index = 0;
        let cardsWidth = (cardCount - 1) * this.cardSpacing + this.cardWidth
        this.cardContainer.x = (window.innerWidth - cardsWidth) / 2
        this.cardContainer.y = window.innerHeight - 195 * this.scaleSize
        let timer = setInterval(() => {
            let props: CardProps = {
                cardNum: cards[index].cardNum,
                cardIcon: cards[index].cardIcon,
                container: this.cardContainer,
                controller: this,
                posX: index * this.cardSpacing,
                scale: this.scaleSize
            }
            let card = new Card(props)
            this.cardMap.set(card.getCardId(), card)
            index++
            if (index === cardCount) { //发牌完毕
                clearInterval(timer);
                this.gainOutCardRight()
            }
        }, 200)
    }

    choiceCard(card: CardType) {
        this.choiceCards.push(card)
        this.choiceCards.sort((a, b) => b.cardNum - a.cardNum)
        this.multipleChoiceCard = card
    }

    cancelChoiceCard(card: CardType) {
        let index = this.choiceCards.findIndex((item => item.cardNum === card.cardNum && item.cardIcon === card.cardIcon))
        if (index !== -1) {
            this.choiceCards.splice(index, 1)
        }
    }

    startMultipleChoice() { this.isMultipleChoice = true }

    stopMultipleChoice() {
        this.isMultipleChoice = false;
        this.multipleChoiceCard = null
    }

    isNowMultipleChoiceCard(card: CardType) {
        if (this.multipleChoiceCard) {
            return this.multipleChoiceCard.cardIcon === card.cardIcon && this.multipleChoiceCard.cardNum === card.cardNum
        }
    }

    initTipCardList() {
        this.calculateTipCardList()
        this.tipCardListLen = this.tipCardList.length
        this.tipCardIndex = 0
    }

    renderLandlord() {
        if (this.model.gameStatus !== GameStatus.Gaming || this.model.landlord !== this.myName) return;
        let landSprite = new PIXI.Sprite(TextureCache['land'])
        landSprite.scale.set(0.7 * this.scaleSize)
        landSprite.x = 5
        landSprite.y = this.cardContainer.y
        this.landlordContainer.addChild(landSprite)
    }

    renderLandlordCard() {
        const cardSpacing = 98 * this.scaleSize
        if (this.model.gameStatus !== GameStatus.Gaming) return;
        this.landCardList.changeCard({
            cardList: this.model.landlordCard,
            posX: (window.innerWidth - cardSpacing * 3) / 2,
            posY: 5,
            cardSpacing,
            isLandCard: true,
            scaleSize: this.scaleSize
        })
    }

    loadOutCard() { // 掉线重连加载自己的出牌信息
        if (this.model.gameStatus !== GameStatus.Gaming) return;
        if (!this.model.isCompleteDouble) return;
        let outCardList = this.model.outCardList
        if (!outCardList) return;
        if (this.outCardButtons.visible) return; // 当前自己出牌，无需渲染
        // 展示出牌
        if (outCardList[this.myName]?.type === OutCardType.EMPTY_CARD_FLAG) return;
        let rawCards = outCardList[this.myName]?.rawCards
        let length = ((rawCards?.length || 0) - 1) * this.cardSpacing + this.cardWidth
        let posX = (window.innerWidth - length) / 2
        let posY = this.cardContainer.y - 160 * this.scaleSize
        this.outCardList.changeCard({ cardList: rawCards, posX, posY, scaleSize: this.scaleSize })
    }

    gameRestart() { // 开始下一局游戏
        // 清除元素
        this.outCardList.clearCard()
        this.landCardList.clearCard()
        this.landlordContainer.removeChildren()
        this.cardContainer.removeChildren()
        this.outCardButtons.visible = false
        this.timer.hidden()
        this.cardMap.clear()
        this.choiceCards = []
        this.isMultipleChoice = false
        this.multipleChoiceCard = null
        this.tipCardList = []
    }

    createGamingItem() {
        if (this.model.gameStatus === GameStatus.Wait) return;
        this.createCards()
        this.createGameButton()
        this.createDoubleButton()
        this.createTimer()
        this.renderLandlord()
        this.renderLandlordCard()
        this.showDoubleButton()
        this.loadOutCard()
    }

    notify(caster: Broadcaster, event: EventType): void {
        let action = event.action
        switch (action) {
            case DataChange.FinishLoad:
                this.createGamingItem()
                break;
            case DataChange.GameStart:
                this.createGamingItem()
                break;
            case DataChange.Double:
                let data = event.data as DoubleMsgType
                if (data.needbroadcast) {
                    this.gainOutCardRight()
                }
                this.showDoubleButton()
                break;
            case DataChange.OutCard:
                this.gainOutCardRight()
                break;
            case DataChange.Restart:
                this.gameRestart()
                break;
            default:
                break;
        }
    }
}